#ifndef __PANEL_DELAY_H__
#define __PANEL_DELAY_H__

#include <wx/wx.h>
#include <wx/aui/aui.h>
#include <wx/wrapsizer.h>
#include <wx/event.h>
#include <wx/xml/xml.h>
#include "MyCommon.h"

class MyEventDelay : public wxCommandEvent {
public:
    MyEventDelay(wxEventType eventType = wxEVT_NULL,int id = 0)
        : wxCommandEvent(eventType, id) {

        }

    // 克隆事件对象
//    [[nodiscard]] // C++17 才支持，意思就是函数返回值不能被忽略，否则编译器发出警告
    virtual wxEvent *Clone() const override {
        return new MyEventDelay(*this);
    }

    void SetTone(double tone) {
        m_tone = tone;
    }
    void SetWet(double wet) {
        m_wet = wet;
    }
    void SetFeedback(double rate) {
        m_rate = rate;
    }
    void SetTime(double time) {
        m_time = time;
    }
    void SetEnable(bool enable) {
        this->enable = enable;
    }
    double GetTone() {
        return m_tone;
    }
    double GetWet() {
        return m_wet;
    }
    double GetFeedback() {
        return m_rate;
    }
    double GetTime() {
        return m_time;
    }
    bool GetEnable() {
        return enable;
    }
    void SetPresetIndex(const unsigned int index) {
        preset_index = index;
    }
    int GetPresetIndex() {
        return preset_index;
    }

private:

    double m_tone;
    double m_wet;
    double m_rate;
    double m_time;
    bool enable;
    int preset_index;
};

wxDECLARE_EVENT(myEVT_DELAY, MyEventDelay);
wxDECLARE_EVENT(myEVT_DELAY_TONE, MyEventDelay);
wxDECLARE_EVENT(myEVT_DELAY_WET, MyEventDelay);
wxDECLARE_EVENT(myEVT_DELAY_FEEDBACK, MyEventDelay);
wxDECLARE_EVENT(myEVT_DELAY_TIME, MyEventDelay);
wxDECLARE_EVENT(myEVT_DELAY_ENABLE, MyEventDelay);

typedef void (wxEvtHandler::*MyDelayEventFunction)(MyEventDelay &);

#define MyDelayEventHandler(func) \
    wxEVENT_HANDLER_CAST(MyDelayEventFunction, func)

#define M_EVT_DELAY(id, fn) \
    wx__DECLARE_EVT1(myEVT_DELAY, id, MyDelayEventHandler(fn))
#define M_EVT_DELAY_TONE(id, fn) \
    wx__DECLARE_EVT1(myEVT_DELAY_TONE, id, MyDelayEventHandler(fn))
#define M_EVT_DELAY_WET(id, fn) \
    wx__DECLARE_EVT1(myEVT_DELAY_WET, id, MyDelayEventHandler(fn))
#define M_EVT_DELAY_FEEDBACK(id, fn) \
    wx__DECLARE_EVT1(myEVT_DELAY_FEEDBACK, id, MyDelayEventHandler(fn))
#define M_EVT_DELAY_TIME(id, fn) \
    wx__DECLARE_EVT1(myEVT_DELAY_TIME, id, MyDelayEventHandler(fn))
#define M_EVT_DELAY_ENABLE(id, fn) \
    wx__DECLARE_EVT1(myEVT_DELAY_ENABLE, id, MyDelayEventHandler(fn))

class PanelDelay : public wxPanel
{
public:
    PanelDelay(const wxString &title, wxXmlNode *node, wxWindowID id = wxID_ANY, wxWindow *parent = nullptr);
    typedef struct
    {
        bool enable;
        float wet;
        float time_ms;
        float tone;
        float feedback;
    }param_struct;

private:

    // enum{
    //     ID_TXT_TONE = ID_START_PANEL_DELAY + 1,
    //     ID_TXT_WET,
    //     ID_TXT_FEEDBACK,
    //     ID_TXT_TIME,
    //     ID_SLI_TONE,
    //     ID_SLI_WET,
    //     ID_SLI_FEEDBACK,
    //     ID_SLI_TIME,
    //     ID_CHK_SWITCH,
    // };

    enum{
        EV_TONE=1,
        EV_WET,
        EV_FEEDBACK,
        EV_TIME,
        EV_ENABLE,
    };

    const double tone_max = 1;
    const double tone_min = 0;
    const double tone_step = 0.01;
    const double wet_max = 6;
    const double wet_min = -30;
    const double wet_step = 0.1;
    const double feedback_max = 1;
    const double feedback_min = 0;
    const double feedback_step = 0.01;
    const double time_max = 0.5;
    const double time_min = 0.05;
    const double time_step = 0.01;

    const char *attr_name_select = "select";
    const char *attr_name_preset_default = "default";
    const char *attr_name_param_enable = "enable";
    const char *attr_name_param_tone = "tone";
    const char *attr_name_param_wet = "wet";
    const char *attr_name_param_feedback = "feedback";
    const char *attr_name_param_time = "time";

    wxWindowID ID_TXT_TONE;
    wxWindowID ID_TXT_WET;
    wxWindowID ID_TXT_FEEDBACK;
    wxWindowID ID_TXT_TIME;
    wxWindowID ID_SLI_TONE;
    wxWindowID ID_SLI_WET;
    wxWindowID ID_SLI_FEEDBACK;
    wxWindowID ID_SLI_TIME;
    wxWindowID ID_CHK_SWITCH;
    wxWindowID ID_CHO_PRESET;


    wxAuiPaneInfo paneInfo;
    MyEventDelay param_event;
    param_struct param;
    wxXmlNode *root_node;
    wxXmlNode *preset_node;
    int select_index;

public:
    wxAuiPaneInfo &GetPaneInfo();
    void SetShow(bool show);
    double SetParamTone(double value);
    double SetParamWet(double value);
    double SetParamFeedback(double value);
    double SetParamTime(double value);
    bool SetParamEnable(bool value);;
    double GetParamTone();
    double GetParamWet();
    double GetParamFeedback();
    double GetParamTime();
    bool GetParamEnable();
    void SetPresetIndex(const unsigned int index);
    int GetPresetIndex();
    void PresetListClear(void);
    void AddPresetList(const wxString &preset_name);
    wxXmlNode *SaveCurrentParamsToNewPreset(wxXmlNode *root, const wxString &new_preset_name,int &is_same);
    bool WriteToXML(wxXmlNode *node);

private:
    void OnSliderChange(wxCommandEvent& event);
    void OnTextEnter(wxCommandEvent& event);
    void OnChkChange(wxCommandEvent& event);
    void OnCombChange(wxCommandEvent& event);

    void TrigerEvent(int ev);
    wxXmlNode *SelectPreset(wxString name);

    // wxDECLARE_EVENT_TABLE();
};


#endif
